// encode: utf-8 (It is best to open using vscode)
// reference video: https://www.bilibili.com/video/BV1QV411m7ff

#include <iostream>
#include <iomanip>
#include <cmath>

class Solution
{
private:
    int m_Size;
    int m_tile;
    int m_Sbx, m_Sby;
    int m_ChessBoardArr[128][128]{};

public:
    Solution(int size, int sbx, int sby)
        : m_Size(size), m_Sbx(sbx), m_Sby(sby), m_tile(1)
    {
        m_ChessBoardArr[m_Sbx][m_Sby] = -1;
    }

    void Filled(int size, int sbx, int sby, int beginX = 0, int beginY = 0)
    {
        int tileNums, subSize;
        if (1 == size)
            return;

        tileNums = m_tile++;
        subSize = size / 2;

        // left-top
        if (sbx < beginX + subSize && sby < beginY + subSize)
        {
            Filled(subSize, sbx, sby, beginX, beginY);
        }
        else
        {
            m_ChessBoardArr[beginX + subSize - 1][beginY + subSize - 1] = tileNums;
            Filled(subSize, beginX + subSize - 1, beginY + subSize - 1, beginX, beginY);
        }

        // right-top
        if (sbx < beginX + subSize && sby >= beginY + subSize)
        {
            Filled(subSize, sbx, sby, beginX, beginY + subSize);
        }
        else
        {
            m_ChessBoardArr[beginX + subSize - 1][beginY + subSize] = tileNums;
            Filled(subSize, beginX + subSize - 1, beginY + subSize, beginX, beginY + subSize);
        }

        // left-bottom
        if (sbx >= beginX + subSize && sby < beginY + subSize)
        {
            Filled(subSize, sbx, sby, beginX + subSize, beginY);
        }
        else
        {
            m_ChessBoardArr[beginX + subSize][beginY + subSize - 1] = tileNums;
            Filled(subSize, beginX + subSize, beginY + subSize - 1, beginX + subSize, beginY);
        }

        // right-bottom
        if (sbx >= beginX + subSize && sby >= beginY + subSize)
        {
            Filled(subSize, sbx, sby, beginX + subSize, beginY + subSize);
        }
        else
        {
            m_ChessBoardArr[beginX + subSize][beginY + subSize] = tileNums;
            Filled(subSize, beginX + subSize, beginY + subSize, beginX + subSize, beginY + subSize);
        }
    }

    void Print()
    {
        std::cout << "\n\tCHESSBOARD" << std::endl;

        for (int i = 0; i < m_Size; i++)
        {
            for (int j = 0; j < m_Size; j++)
            {
                std::cout << std::setw(3) << m_ChessBoardArr[i][j];
            }
            std::cout << std::endl;
        }
    }
};

int main()
{
    int size, n, sbx, sby;
    std::cout << "Input n(size = 2**n)" << std::endl;
    std::cin >> n;
    size = pow(2, n);
    std::cout << "Input the position of special block(sb's x,sb's y):" << std::endl;
    std::cin >> sbx >> sby;

    Solution slt(size, sbx, sby);
    slt.Print();
    slt.Filled(size, sbx, sby);
    slt.Print();
}